home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Ang261Lib.lha / src / death.c < prev    next >
C/C++ Source or Header  |  1994-10-22  |  17KB  |  636 lines

  1. /*
  2.  * death.c: code executed when player dies 
  3.  *
  4.  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke 
  5.  *
  6.  * This software may be copied and distributed for educational, research, and
  7.  * not for profit purposes provided that this copyright and statement are
  8.  * included in all such copies. 
  9.  */
  10.  
  11. /*
  12.  * some incorrectly define NULL as integer constant, so load this before
  13.  * local includes 
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <signal.h>
  18. #include "config.h"
  19. #include "constant.h"
  20. #include "types.h"
  21. #include "externs.h"
  22.  
  23. #ifdef Pyramid
  24. #include <sys/time.h>
  25. #else
  26. #include <time.h>
  27. #endif
  28.  
  29. #include <ctype.h>
  30. #include "config.h"
  31.  
  32. #ifndef USG
  33. /* only needed for Berkeley UNIX */
  34. #include <sys/param.h>
  35. #include <sys/types.h>
  36. #include <sys/file.h>
  37. #else
  38. #ifdef __MINT__        
  39. #include <sys/types.h>
  40. #endif
  41. #include <unistd.h>
  42. #endif
  43.  
  44. #ifdef MSDOS
  45. #include <io.h>
  46. #else
  47. #if !defined(ATARIST_MWC) && !defined(MAC)
  48. #ifndef VMS
  49. #include <pwd.h>
  50. #else
  51. #include <file.h>
  52. #endif
  53. #endif
  54. #endif
  55.  
  56. #ifdef linux
  57. #include <sys/file.h>
  58. #endif
  59.  
  60. #ifdef USG
  61. #ifndef ATARIST_MWC
  62. #include <string.h>
  63. #include <fcntl.h>
  64. #endif
  65. #else
  66. #include <strings.h>
  67. #endif
  68.  
  69. #if defined(USG) || defined(VMS)
  70. #ifndef L_SET
  71. #define L_SET 0
  72. #endif
  73. #endif
  74.  
  75. #ifndef VMS
  76. #ifndef MAC
  77. #if defined(ultrix) || defined(USG)
  78. void                perror();
  79. void                exit();
  80.  
  81. #endif
  82. #endif
  83. #endif
  84.  
  85. #ifndef MAC
  86. #ifdef SYS_V
  87. struct passwd      *getpwuid();
  88.  
  89. #endif
  90. #endif
  91.  
  92. /* Lets do all prototypes correctly.... -CWS */
  93. #ifndef NO_LINT_ARGS
  94. #ifdef __STDC__
  95. static void  date(char *);
  96. static char *center_string(char *, const char *);
  97. static void  print_tomb(void);
  98. static void  kingly(void);
  99.  
  100. #else
  101. static void  date();
  102. static char *center_string();
  103. static void  print_tomb();
  104. static void  kingly();
  105.  
  106. #endif
  107. #endif
  108.  
  109. #ifndef MAC
  110. char        *getlogin();
  111. #endif
  112.  
  113. #if !defined(time_t)
  114. #define time_t long
  115. #endif
  116.  
  117. static void 
  118. date(day)
  119. char *day;
  120. {
  121.     register char *tmp;
  122.     time_t         c;
  123.  
  124.     c = time((time_t *)0);
  125.     tmp = ctime(&c);
  126.     tmp[10] = '\0';
  127.     (void)strcpy(day, tmp);
  128. }
  129.  
  130. /* Centers a string within a 31 character string        -JWT-     */
  131. static char *
  132. center_string(centered_str, in_str)
  133. char       *centered_str;
  134. const char *in_str;
  135. {
  136.     register int i, j;
  137.  
  138.     i = strlen(in_str);
  139.     j = 15 - i / 2;
  140.     (void)sprintf(centered_str, "%*s%s%*s", j, "", in_str, 31 - i - j, "");
  141.     return centered_str;
  142. }
  143.  
  144.  
  145. /* Not touched for Mac port */
  146. void 
  147. display_scores(from, to)
  148. int from, to;
  149. {
  150.     register int i = 0, j, k, l;
  151.     int          fd;
  152.     high_scores  score;
  153.  
  154. /* MAX_SAVE_HISCORES scores, 2 lines per score */
  155.     char         list[2 * MAX_SAVE_HISCORES][128];
  156.     char         hugebuffer[10000];
  157.     char         string[100];
  158.  
  159.     vtype        tmp_str;
  160.  
  161.     if (to < 0)
  162.     to = 20;
  163.     if (to > MAX_SAVE_HISCORES)
  164.     to = MAX_SAVE_HISCORES;
  165. #ifdef SET_UID
  166.     if (1 > (fd = my_topen(ANGBAND_TOP, O_RDONLY | O_CREAT, 0644))) {
  167. #else
  168.     if (1 > (fd = my_topen(ANGBAND_TOP, O_RDONLY | O_CREAT, 0666))) {
  169. #endif
  170.     (void)sprintf(string, "Error opening score file \"%s\"\n", ANGBAND_TOP);
  171.     prt(string, 0, 0);
  172.     return;
  173.     }
  174.     while (0 < read(fd, (char *)&score, sizeof(high_scores))) {
  175.     if (score.uid != -1 && getpwuid(score.uid) != NULL)
  176.         (void)sprintf(hugebuffer, "%3d) %-7ld %s the %s %s (Level %d), played by %s",
  177.               i / 2 + 1,
  178.               (long)score.points, score.name,
  179.               race[score.prace].trace, class[score.pclass].title,
  180.               (int)score.lev, getpwuid(score.uid)->pw_name);
  181.     else
  182.         (void)sprintf(hugebuffer, "%3d) %-7ld %s the %s %s (Level %d)",
  183.               i / 2 + 1,
  184.               (long)score.points, score.name,
  185.               race[score.prace].trace, class[score.pclass].title,
  186.               (int)score.lev);
  187.     strncpy(list[i], hugebuffer, 127);
  188.     (void)sprintf(hugebuffer,
  189.               "             Killed by %s on Dungeon Level %d.",
  190.               score.died_from, score.dun_level);
  191.     strncpy(list[i + 1], hugebuffer, 127);
  192.     i += 2;
  193.     if (i >= (MAX_SAVE_HISCORES * 2))
  194.         break;
  195.     }
  196.  
  197.     signal(SIGTSTP, SIG_IGN);
  198.     k = from * 2;
  199.     do {
  200.     if (k > 0) {
  201.         sprintf(tmp_str, "\t\tAngband Hall of Fame (from position %d)",
  202.             (k / 2) + 1);
  203.         put_buffer(tmp_str, 0, 0);
  204.     } else {
  205.         put_buffer("\t\tAngband Hall of Fame                     ", 0, 0);
  206.     }
  207.     put_buffer("     Score", 1, 0);
  208.     l = 0;
  209.     for (j = k; j < i && j < (to * 2) && j < (k + 20); j++, l++)
  210.         put_buffer(list[j], l + 2, 0);
  211.     k += 20;
  212.     if (!look_line(23)) {
  213.     /* What happens upon dying.                -RAK-     */
  214.         msg_print(NULL);
  215.         clear_screen();
  216.         flush();           /* flush all input */
  217.         nosignals();       /* Can't interrupt or suspend. */
  218.         (void)save_char();       /* Save the memory at least. */
  219.         restore_term();
  220.         exit(0);
  221.     }
  222.     clear_screen();
  223.     } while (k < (to * 2) && k < i);
  224. }
  225.  
  226. /* Pauses for user response before returning        -RAK-     */
  227. int 
  228. look_line(prt_line)
  229. int prt_line;
  230. {
  231.     prt("[Press ESC to quit, any other key to continue.]", prt_line, 17);
  232.     if (inkey() == ESCAPE) {
  233.     erase_line(prt_line, 0);
  234.     return 0;
  235.     } else {
  236.     erase_line(prt_line, 0);
  237.     return 1;
  238.     }
  239. }
  240.  
  241.  
  242.  
  243. /* Prints the gravestone of the character        -RAK-     */
  244. static void 
  245. print_tomb()
  246. {
  247.     vtype                str, tmp_str;
  248.     register int         i;
  249.     char                 day[11];
  250.     register const char *p;
  251.     FILE                *fp;
  252.  
  253.     if (stricmp(died_from, "Interrupting") && !wizard) {
  254.     sprintf(str, "%s/%d", ANGBAND_BONES, dun_level);
  255.     if ((fp = my_tfopen(str, "r")) == NULL && (dun_level > 1)) {
  256.         if ((fp = my_tfopen(str, "w")) != NULL) {
  257. #ifndef __MINT__
  258. #ifdef SET_UID
  259.         (void)fchmod(fileno(fp), 0644);
  260. #else
  261.         (void)fchmod(fileno(fp), 0666);
  262. #endif
  263. #endif
  264.         fprintf(fp, "%s\n%d\n%d\n%d",
  265.           py.misc.name, py.misc.mhp, py.misc.prace, py.misc.pclass);
  266.         if (fp) fclose(fp);
  267.         }
  268.     } else {
  269.         if (fp) fclose(fp);
  270.     }
  271.     }
  272.     clear_screen();
  273.     put_buffer("_______________________", 1, 15);
  274.     put_buffer("/", 2, 14);
  275.     put_buffer("\\         ___", 2, 38);
  276.     put_buffer("/", 3, 13);
  277.     put_buffer("\\ ___   /   \\      ___", 3, 39);
  278.     put_buffer("/            RIP            \\   \\  :   :     /   \\", 4, 12);
  279.     put_buffer("/", 5, 11);
  280.     put_buffer("\\  : _;,,,;_    :   :", 5, 41);
  281.     (void)sprintf(str, "/%s\\,;_          _;,,,;_",
  282.           center_string(tmp_str, py.misc.name));
  283.     put_buffer(str, 6, 10);
  284.     put_buffer("|               the               |   ___", 7, 9);
  285.     if (!total_winner)
  286.     p = title_string();
  287.     else
  288.     p = "Magnificent";
  289.     (void)sprintf(str, "| %s |  /   \\", center_string(tmp_str, p));
  290.     put_buffer(str, 8, 9);
  291.     put_buffer("|", 9, 9);
  292.     put_buffer("|  :   :", 9, 43);
  293.     if (!total_winner)
  294.     p = class[py.misc.pclass].title;
  295.     else if (py.misc.male)
  296.     p = "*King*";
  297.     else
  298.     p = "*Queen*";
  299.     (void)sprintf(str, "| %s | _;,,,;_   ____", center_string(tmp_str, p));
  300.     put_buffer(str, 10, 9);
  301.     (void)sprintf(str, "Level : %d", (int)py.misc.lev);
  302.     (void)sprintf(str, "| %s |          /    \\", center_string(tmp_str, str));
  303.     put_buffer(str, 11, 9);
  304.     (void)sprintf(str, "%ld Exp", (long)py.misc.exp);
  305.     (void)sprintf(str, "| %s |          :    :", center_string(tmp_str, str));
  306.     put_buffer(str, 12, 9);
  307.     (void)sprintf(str, "%ld Au", (long)py.misc.au);
  308.     (void)sprintf(str, "| %s |          :    :", center_string(tmp_str, str));
  309.     put_buffer(str, 13, 9);
  310.     (void)sprintf(str, "Died on Level : %d", dun_level);
  311.     (void)sprintf(str, "| %s |         _;,,,,;_", center_string(tmp_str, str));
  312.     put_buffer(str, 14, 9);
  313.     put_buffer("|            killed by            |", 15, 9);
  314.     p = died_from;
  315.     i = strlen(p);
  316.     died_from[i] = '.';               /* add a trailing period */
  317.     died_from[i + 1] = '\0';
  318.     (void)sprintf(str, "| %s |", center_string(tmp_str, p));
  319.     put_buffer(str, 16, 9);
  320.     died_from[i] = '\0';           /* strip off the period */
  321.     date(day);
  322.     (void)sprintf(str, "| %s |", center_string(tmp_str, day));
  323.     put_buffer(str, 17, 9);
  324.     put_buffer("*|   *     *     *    *   *     *  | *", 18, 8);
  325.     put_buffer("________)/\\\\_)_/___(\\/___(//_\\)/_\\//__\\\\(/_|_)_______",
  326.            19, 0);
  327.  
  328.     flush();
  329.     put_buffer("(ESC to abort, return to print on screen, or file name)", 23, 0);
  330.     put_buffer("Character record?", 22, 0);
  331.     if (get_string(str, 22, 18, 60)) {
  332.     for (i = 0; i < INVEN_ARRAY_SIZE; i++) {
  333.         inven_type *i_ptr = &inventory[i];
  334.         if (i_ptr && i_ptr->tval != TV_NOTHING) {
  335.         known1(i_ptr);
  336.         known2(i_ptr);
  337.         }
  338.     }
  339.     calc_bonuses();
  340.     clear_screen();
  341.     display_char();
  342.     put_buffer("Type ESC to skip the inventory:", 23, 0);
  343.     if (inkey() != ESCAPE) {
  344.         clear_screen();
  345.         msg_print("You are using:");
  346.         (void)show_equip(TRUE, 0);
  347.         msg_print(NULL);
  348.         if (inven_ctr) {
  349.         msg_print("You are carrying:");
  350.         clear_from(1);
  351.         (void)show_inven(0, inven_ctr - 1, TRUE, 0, 0);
  352.         msg_print(NULL);
  353.         }
  354.           msg_print ("You have stored at your house:");
  355.           clear_from (1);
  356.     { /* show home's inventory... */
  357.             store_type *s_ptr = &store[7]; /* home */
  358.             int ii = 0, j = 0;
  359.             vtype t1, t2;
  360.             
  361.             while ( ii <s_ptr->store_ctr) {
  362.               j = 0;
  363.               sprintf(t2, "(page %d)", (ii==0?1:2));
  364.               prt(t2, 1, 3);
  365.               while ((ii<s_ptr->store_ctr) && (j<12)){
  366.                 known1(&s_ptr->store_inven[ii].sitem);
  367.                 known2(&s_ptr->store_inven[ii].sitem);
  368.                 objdes(t1, &s_ptr->store_inven[ii].sitem, TRUE);
  369.                 sprintf(t2, "%c) %s", 'a'+j, t1);
  370.                 prt(t2, j+2, 4); 
  371.                 j++;
  372.                 ii++;
  373.         } /* items 1-12, 13-24 loop */
  374.               if (ii < s_ptr->store_ctr) { /* if we're done, skip this */
  375.                 msg_print(NULL);
  376.                 msg_print("Home inventory:");
  377.                 clear_from (1);
  378.         }
  379.       } /* outer while loop */
  380.             msg_print(NULL);
  381.     } /* scope block of display-home inventory code -CFT */
  382.  
  383.     }
  384.     }
  385. }
  386.  
  387.  
  388. /* Calculates the total number of points earned        -JWT-     */
  389. long 
  390. total_points()
  391. {
  392.     return (py.misc.max_exp + (100 * py.misc.max_dlv));
  393. }
  394.  
  395.  
  396.  
  397. /* Enters a players name on a hi-score table...    SM */
  398. static int 
  399. top_twenty()
  400. {
  401.     register int        i, j, k;
  402.     high_scores         scores[MAX_SAVE_HISCORES], myscore;
  403.  
  404.     clear_screen();
  405.  
  406.     if (wizard || to_be_wizard) {
  407.     display_scores(0, 10);
  408.     (void)save_char();
  409.     restore_term();
  410.     exit(0);
  411.     }
  412.     if (!total_winner && !stricmp(died_from, "Interrupting")) {
  413.     msg_print("Score not registered due to interruption.");
  414.     display_scores(0, 10);
  415.     (void)save_char();
  416.     restore_term();
  417.     exit(0);
  418.     }
  419.     if (!total_winner && !stricmp(died_from, "Quitting")) {
  420.     msg_print("Score not registered due to quitting.");
  421.     display_scores(0, 10);
  422.     (void)save_char();
  423.     restore_term();
  424.     exit(0);
  425.     }
  426.     myscore.points = total_points();
  427.     myscore.dun_level = dun_level;
  428.     myscore.lev = py.misc.lev;
  429.     myscore.max_lev = py.misc.max_dlv;
  430.     myscore.mhp = py.misc.mhp;
  431.     myscore.chp = py.misc.chp;
  432.     myscore.uid = player_uid;
  433. /* First character of sex, lower case */
  434.     myscore.sex = py.misc.male;
  435.     myscore.prace = py.misc.prace;
  436.     myscore.pclass = py.misc.pclass;
  437.     (void)strcpy(myscore.name, py.misc.name);
  438.     (void)strncpy(myscore.died_from, died_from, strlen(died_from));
  439.     myscore.died_from[strlen(died_from)] = '\0';
  440. /* Get rid of '.' at end of death description */
  441.  
  442. /* First, get a lock on the high score file so no-one else tries */
  443. /* to write to it while we are using it */
  444. /* added sys_v call to lockf - cba */
  445. #ifdef USG
  446.     if (lockf(highscore_fd, F_LOCK, 0) != 0)
  447. #else
  448.     if (0 != flock(highscore_fd, LOCK_EX))
  449. #endif
  450.     {
  451.     perror("Error gaining lock for score file");
  452.     exit_game();
  453.     }
  454. /* Check to see if this score is a high one and where it goes */
  455.     i = 0;
  456. #ifndef BSD4_3
  457.     (void)lseek(highscore_fd, (long)0, L_SET);
  458. #else
  459.     (void)lseek(highscore_fd, (off_t) 0, L_SET);
  460. #endif
  461.     while ((i < MAX_SAVE_HISCORES)
  462.     && (0 != read(highscore_fd, (char *)&scores[i], sizeof(high_scores)))) {
  463.     i++;
  464.     }
  465.  
  466.     j = 0;
  467.     while (j < i && (scores[j].points >= myscore.points)) {
  468.     j++;
  469.     }
  470. /* i is now how many scores we have, and j is where we put this score */
  471.  
  472. /* If its the first score, or it gets appended to the file */
  473.     if (!i || (i == j && j < MAX_SAVE_HISCORES)) {
  474.     (void)lseek(highscore_fd, (long)(j * sizeof(high_scores)), L_SET);
  475.     (void)write(highscore_fd, (char *)&myscore, sizeof(high_scores));
  476.     } else if (j < i) {
  477.     /* If it gets inserted in the middle */
  478.     /* Bump all the scores up one place */
  479.     for (k = MY_MIN(i, (MAX_SAVE_HISCORES - 1)); k > j; k--) {
  480.         (void)lseek(highscore_fd, (long)(k * sizeof(high_scores)), L_SET);
  481.         (void)write(highscore_fd, (char *)&scores[k - 1], sizeof(high_scores));
  482.     }
  483.     /* Write out your score */
  484.     (void)lseek(highscore_fd, (long)(j * sizeof(high_scores)), L_SET);
  485.     (void)write(highscore_fd, (char *)&myscore, sizeof(high_scores));
  486.     }
  487. /* added usg lockf call - cba */
  488. #ifdef USG
  489.     lockf(highscore_fd, F_ULOCK, 0);
  490. #else
  491.     (void)flock(highscore_fd, LOCK_UN);
  492. #endif
  493.     (void)close(highscore_fd);
  494.     if (j < 10) {
  495.     display_scores(0, 10);
  496.     } else if (j > (i - 5)) {
  497.     display_scores(i - 9, i + 1);
  498.     } else
  499.     display_scores(j - 5, j + 5);
  500.     return (0);
  501. }
  502.  
  503. /* Enters a players name on the hi-score table     SM     */
  504. void 
  505. delete_entry(which)
  506. int which;
  507. {
  508.     register int i;
  509.     high_scores  scores[MAX_SAVE_HISCORES];
  510.  
  511. /* added usg lockf call - cba */
  512. #ifdef USG
  513.     if (lockf(highscore_fd, F_LOCK, 0) != 0)
  514. #else
  515.     if (0 != flock(highscore_fd, LOCK_EX))
  516. #endif
  517.     {
  518.     perror("Error gaining lock for score file");
  519.     exit_game();
  520.     }
  521. /* Check to see if this score is a high one and where it goes */
  522.     i = 0;
  523.     (void)lseek(highscore_fd, (off_t) 0, L_SET);
  524.     while ((i < MAX_SAVE_HISCORES) &&
  525.      (0 != read(highscore_fd, (char *)&scores[i], sizeof(high_scores))))
  526.     i++;
  527.  
  528.     if (i >= which) {
  529.  
  530. #if defined(sun) || defined(ultrix) || defined(NeXT)
  531.     ftruncate(highscore_fd, 0);
  532. #endif
  533.  
  534. /* If its the first score, or it gets appended to the file */
  535.     lseek(highscore_fd, 0, L_SET);
  536.     if (which > 0)
  537.         write(highscore_fd, (char *)&scores[0],
  538.           (which - 1) * sizeof(high_scores));
  539.     if (i > which)
  540.         write(highscore_fd, (char *)&scores[which],
  541.           (i - which) * sizeof(high_scores));
  542.     } else {
  543.         puts(" The high score table does not have that many entries!");
  544.     }
  545.  
  546. /* added usg lockf call - cba */
  547. #ifdef USG
  548.     lockf(highscore_fd, F_ULOCK, 0);
  549. #else
  550.     (void)flock(highscore_fd, LOCK_UN);
  551. #endif
  552.     (void)close(highscore_fd);
  553.     if (which < 10) {
  554.     display_scores(0, 10);
  555.     } else if (which > (i - 10)) {
  556.     display_scores(i - 10, i);
  557.     } else
  558.     display_scores(which - 5, which + 5);
  559. }
  560.  
  561. /* Change the player into a King!            -RAK-     */
  562. static void 
  563. kingly()
  564. {
  565.     register struct misc *p_ptr;
  566.     register const char  *p;
  567.  
  568. /* Change the character attributes.         */
  569.     dun_level = 0;
  570.     (void)strcpy(died_from, "Ripe Old Age");
  571.     p_ptr = &py.misc;
  572.     (void)restore_level();
  573.     p_ptr->lev += MAX_PLAYER_LEVEL;
  574.     p_ptr->au += 250000L;
  575.     p_ptr->max_exp += 5000000L;
  576.     p_ptr->exp = p_ptr->max_exp;
  577.  
  578. /* Let the player know that he did good.     */
  579.     clear_screen();
  580.     put_buffer("#", 1, 34);
  581.     put_buffer("#####", 2, 32);
  582.     put_buffer("#", 3, 34);
  583.     put_buffer(",,,  $$$  ,,,", 4, 28);
  584.     put_buffer(",,=$   \"$$$$$\"   $=,,", 5, 24);
  585.     put_buffer(",$$        $$$        $$,", 6, 22);
  586.     put_buffer("*>         <*>         <*", 7, 22);
  587.     put_buffer("$$         $$$         $$", 8, 22);
  588.     put_buffer("\"$$        $$$        $$\"", 9, 22);
  589.     put_buffer("\"$$       $$$       $$\"", 10, 23);
  590.     p = "*#########*#########*";
  591.     put_buffer(p, 11, 24);
  592.     put_buffer(p, 12, 24);
  593.     put_buffer("Veni, Vidi, Vici!", 15, 26);
  594.     put_buffer("I came, I saw, I conquered!", 16, 21);
  595.     if (p_ptr->male)
  596.     put_buffer("All Hail the Mighty King!", 17, 22);
  597.     else
  598.     put_buffer("All Hail the Mighty Queen!", 17, 22);
  599.     flush();
  600.     pause_line(23);
  601. }
  602.  
  603.  
  604. /* Handles the gravestone end top-twenty routines    -RAK-     */
  605. void 
  606. exit_game()
  607. {
  608.     register int        i;
  609.  
  610. #ifdef MAC
  611. /* Prevent strange things from happening */
  612.     enablefilemenu(FALSE);
  613. #endif
  614.  
  615. /* What happens upon dying.                -RAK-     */
  616.     msg_print(NULL);
  617.     flush();               /* flush all input */
  618.     nosignals();           /* Can't interrupt or suspend. */
  619.     if (turn >= 0) {
  620.     if (total_winner)
  621.         kingly();
  622.     print_tomb();
  623.     if (!wizard && !to_be_wizard)
  624.         top_twenty();
  625.     else
  626.         msg_print("Score not registered.");
  627.     }
  628.     i = log_index;
  629.     (void)save_char();           /* Save the memory at least. */
  630.     if (i > 0)
  631.     display_scores(0, 10);
  632.     erase_line(23, 0);
  633.     restore_term();
  634.     exit(0);
  635. }
  636.